﻿#region Copyright (C) Sector7 Software Studio. All rights reserved
/*******************************************************************************************
 * Creation
 *      Author:         Wolf Lai
 *      Date:           2011/10/27 21:47:23
 *      Version:        1.0.1101
 * Modification 
 *      Author: 
 *      Date: 
 *      Description: 
 *      Version:
 *******************************************************************************************/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using System.IO;
using Sector7.Framework.Enums;
using Sector7.Framework.Utility;

namespace Sector7.Framework.Core
{
    /// <summary>
    /// 日志类
    /// </summary>                
    public static class Log
    {
        #region Inner members
        /// <summary>
        /// 指示日志类是否完成初始化
        /// </summary>
        private static bool m_initialized = false;

        /// <summary>
        /// 指示是否启用日志功能
        /// </summary>
        private static bool m_enabled = false;

        /// <summary>
        /// 日志文件存放路径
        /// </summary>
        private static string m_path = string.Empty;

        /// <summary>
        /// 行号
        /// </summary>
        private static int m_lineNo = 0;

        /// <summary>
        /// 日志记录级别（0 - Error; 1 - Information; 2 - Warning; 3 - Debug）
        /// </summary>
        private static int m_logSeverity = 3;
        #endregion

        #region Accessor
        /// <summary>
        /// 获取是否启用日志功能标识
        /// </summary>
        public static bool Enabled
        {
            get { return m_enabled; }
        }

        /// <summary>
        /// 获取日志文件存放路径
        /// </summary>
        public static string Path
        {
            get { return m_path; }
        }
        #endregion

        #region Structure
        /// <summary>
        /// 创建日志记录类
        /// </summary>
        static Log()
        {
            m_enabled = true;
            m_path = string.Format(
                "{0}Logs",
                ApplicationUtil.GetBaseDirectory());
        }
        #endregion

        #region Public functions
        /// <summary>
        /// 初始化日志类
        /// </summary>
        /// <param name="enabled">是否启用日志功能标识</param>
        /// <param name="path">日志文件存放路径</param>
        public static void Initialize(bool enabled, string path)
        {
            if (!m_initialized)
            {
                m_lineNo = 0;
                m_enabled = enabled;
                m_path = path;
                m_initialized = true;
            }
        }

        /// <summary>
        /// 记录日志
        /// </summary>
        /// <param name="logSeverity">日志类型</param>
        /// <param name="logModule">模块名称</param>
        /// <param name="value">要写入日志的值</param>
        public static void WriteLine(LogSeverityType logSeverity, string logModule, object value)
        {
            WriteLine(logSeverity, logModule, null, value);
        }

        /// <summary>
        /// 记录日志
        /// </summary>
        /// <param name="logSeverity">日志类型</param>
        /// <param name="format">复合格式字符串</param>
        /// <param name="logModule">模块名称</param>
        /// <param name="values">要写入日志的值列表</param>
        public static void WriteLine(LogSeverityType logSeverity, string logModule, string format, params object[] values)
        {
            if (m_enabled && (m_logSeverity >= Convert.ToInt32(logSeverity)))
            {
                TextWriter writer = GetWriter();

                if (writer != null)
                {
                    writer.WriteLine(string.Format(GetFormat(logSeverity, logModule, format), values));
                    writer.Flush();

                    GCUtil.CloseStream(writer);
                }
            }
        }
        #endregion

        #region Private functions
        /// <summary>
        /// 获取日志类IO对象
        /// </summary>
        /// <returns></returns>
        private static StreamWriter GetWriter()
        {
            StreamWriter writer = null;

            try
            {
                PathUtil.CheckExists(m_path);

                string logName = string.Format(
                    "{0}\\{1}.log",
                    m_path,
                    DateTime.Now.ToString("yyyy.MM.dd"));

                if (!File.Exists(logName))
                {
                    writer = File.CreateText(logName);
                }
                else
                {
                    writer = File.AppendText(logName);
                }
            }
            catch (Exception)
            {
                GCUtil.CloseStream(writer);
            }

            return writer;
        }

        /// <summary>
        /// 获取日志输出格式化字符串
        /// </summary>
        /// <param name="logSeverity">日志类型</param>
        /// <param name="logModule">模块名称</param>
        /// <param name="format">复合格式字符串</param>
        /// <returns></returns>
        private static string GetFormat(LogSeverityType logSeverity, string logModule, string format)
        {
            if (format == null)
                format = "{0}";

            StackFrame stackFrame = new StackTrace(true).GetFrame(2);
            MethodBase method = stackFrame.GetMethod();

            string className = method.DeclaringType.Name;

            return string.Format( //LINE_NO <DATE_TIME> APPLICATION_NAME THREAD_ID SEVERITY/MODULE_NAME/CLASS_NAME# PRINTS
                "{0:000000} <{1}> {2} {3:X2} {4}/{5}/{6}# {7}",
                ++m_lineNo,
                DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss:ffffff"),
                AppDomain.CurrentDomain.FriendlyName,
                System.Threading.Thread.CurrentThread.GetHashCode(),
                logSeverity,
                logModule,
                className,
                format);
        }
        #endregion
    }
}
